home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_300 / 335_04 / fraosub.c < prev    next >
C/C++ Source or Header  |  1990-12-02  |  15KB  |  793 lines

  1. /*
  2. HEADER:     ;
  3. TITLE:         Frankenstein Cross Assemblers;
  4. VERSION:     2.0;
  5. DESCRIPTION: "    Reconfigurable Cross-assembler producing Intel (TM)
  6.         Hex format object records.  ";
  7. SYSTEM:     UNIX, MS-Dos ;
  8. FILENAME:     fraosub.c;
  9. WARNINGS:     "This software is in the public domain.  
  10.         Any prior copyright claims are relinquished.  
  11.  
  12.         This software is distributed with no warranty whatever.  
  13.         The author takes no responsibility for the consequences 
  14.         of its use."  ;
  15. SEE-ALSO:     frasmain.c;
  16. AUTHORS:     Mark Zenier;
  17. */
  18.  
  19. /*
  20.     description    output pass utility routines
  21.     history        September 27, 1987
  22.             March 15, 1988   release 1.1 WIDTH
  23.             September 14, 1990  Dosify, 6 char unique names
  24. */
  25.  
  26.  
  27. #include <stdio.h>
  28. #include "frasmdat.h"
  29. #include "fragcon.h"
  30.  
  31. #define OUTRESULTLEN 256
  32. #define NUMHEXPERL 16
  33. #define SOURCEOFFSET 24
  34. #define NUMHEXSOURCE 6
  35.  
  36. int linenumber = 0;
  37. char lineLbuff[INBUFFSZ];
  38. int lineLflag = FALSE;
  39.  
  40. static unsigned char    outresult[OUTRESULTLEN];
  41. static int    nextresult;
  42. static long     genlocctr, resultloc;
  43.  
  44. static char    *oeptr;
  45.  
  46. #define    MAXIMPWID    24
  47.  
  48. static long widthmask[MAXIMPWID+1] =
  49. {
  50. /* 0 */        1L,
  51. /* 1 */        1L,
  52. /* 2 */        (1L <<  2 ) -1,
  53. /* 3 */        (1L <<  3 ) -1,
  54. /* 4 */        (1L <<  4 ) -1,
  55. /* 5 */        (1L <<  5 ) -1,
  56. /* 6 */        (1L <<  6 ) -1,
  57. /* 7 */        (1L <<  7 ) -1,
  58. /* 8 */        (1L <<  8 ) -1,
  59. /* 9 */        (1L <<  9 ) -1,
  60. /* 10 */    (1L <<  10 ) -1,
  61. /* 11 */    (1L <<  11 ) -1,
  62. /* 12 */    (1L <<  12 ) -1,
  63. /* 13 */    (1L <<  13 ) -1,
  64. /* 14 */    (1L <<  14 ) -1,
  65. /* 15 */    (1L <<  15 ) -1,
  66. /* 16 */    (1L <<  16 ) -1,
  67. /* 17 */    (1L <<  17 ) -1,
  68. /* 18 */    (1L <<  18 ) -1,
  69. /* 19 */    (1L <<  19 ) -1,
  70. /* 20 */    (1L <<  20 ) -1,
  71. /* 21 */    (1L <<  21 ) -1,
  72. /* 22 */    (1L <<  22 ) -1,
  73. /* 23 */    (1L <<  23 ) -1,
  74. /* 24 */    (1L <<  24 ) -1
  75. };
  76.     
  77.  
  78. static long dgethex()
  79. /*
  80.     description    convert the character string pointed to by
  81.             the output expression pointer to a long integer
  82.     globals        oeptr, the output expression pointer
  83.     return        the value
  84. */
  85. {
  86.     long rv = 0;
  87.  
  88.     while( *oeptr != '\0')
  89.     {
  90.         switch(*oeptr)
  91.         {
  92.         case '0':
  93.         case '1':
  94.         case '2':
  95.         case '3':
  96.         case '4':
  97.         case '5':
  98.         case '6':
  99.         case '7':
  100.         case '8':
  101.         case '9':
  102.             rv = (rv << 4) + ((*oeptr) - '0');
  103.             break;
  104.  
  105.         case 'a':
  106.         case 'b':
  107.         case 'c':
  108.         case 'd':
  109.         case 'e':
  110.         case 'f':
  111.             rv = (rv << 4) + ((*oeptr) - 'a' + 10);
  112.             break;
  113.         
  114.         case 'A':
  115.         case 'B':
  116.         case 'C':
  117.         case 'D':
  118.         case 'E':
  119.         case 'F':
  120.             rv = (rv << 4) + ((*oeptr) - 'A' + 10);
  121.             break;
  122.  
  123.         default:
  124.             return rv;
  125.         }
  126.  
  127.         oeptr++;
  128.     }
  129.  
  130.     return rv;
  131. }
  132.     
  133.  
  134. outphase()
  135. /*
  136.     description    process all the lines in the intermediate file
  137.     globals        the input line
  138.             the output expression pointer
  139.             line number
  140.             file name
  141.             the binary output array and counts
  142. */
  143. {
  144.     int firstchar;
  145.  
  146.     for(;;)
  147.     {
  148.         if((firstchar = fgetc(intermedf)) == EOF)
  149.             break;
  150.  
  151.         if(firstchar == 'L')
  152.         {
  153.             if(listflag)
  154.                 flushlisthex();
  155.  
  156.             if( fgets(&lineLbuff[1], INBUFFSZ-1, intermedf) 
  157.              == (char *)NULL)
  158.             {
  159.         frp2error( "error or premature end of intermediate file");
  160.                 break;
  161.             }
  162.  
  163.             lineLflag = TRUE;
  164.         }
  165.         else
  166.         {
  167.             finbuff[0] = firstchar;
  168.             if(fgets( &finbuff[1], INBUFFSZ-1, intermedf) 
  169.              == (char *)NULL)
  170.             {
  171.         frp2error("error or premature end of intermediate file");
  172.                 break;
  173.             }
  174.         }
  175.     
  176.         switch(firstchar)
  177.         {
  178.         case 'E': /* error */
  179.             if(listflag)
  180.             {
  181.                 flushsourceline();
  182.                 fputs(&finbuff[2], loutf);
  183.             }
  184.             else
  185.             {
  186.                 fprintf(loutf, "%s - line %d - %s", 
  187.                     currentfnm, linenumber, &finbuff[2]);
  188.             }
  189.             break;
  190.  
  191.         case 'L': /* listing */
  192.             linenumber++;
  193.             break;
  194.  
  195.         case 'C': /* comment / uncounted listing */
  196.             if(listflag)
  197.             {
  198.                 char *stuff = strchr(finbuff, '\n');
  199.  
  200.                 if(stuff != NULL)
  201.                     *stuff = '\0';
  202.  
  203.                 fprintf(loutf,"%-*.*s", 
  204.                  SOURCEOFFSET, SOURCEOFFSET, &finbuff[2]);
  205.                 if(lineLflag)
  206.                 {
  207.                     fputs(&lineLbuff[2], loutf);
  208.                     lineLflag = FALSE;
  209.                 }
  210.                 else
  211.                 {
  212.                     fputc('\n', loutf);
  213.                 }
  214.             }
  215.             break;
  216.  
  217.         case 'P': /* location set */
  218.             oeptr = &finbuff[2];
  219.             currseg = dgethex();
  220.             oeptr++;
  221.             genlocctr = locctr = dgethex();
  222.             break;
  223.         
  224.         case 'D': /* data */
  225.             oeptr = &finbuff[2];
  226.             nextresult = 0;
  227.             resultloc = genlocctr;
  228.             outeval();
  229.             if(hexflag)
  230.                 outhexblock();
  231.             if(listflag)
  232.                 listhex();
  233.             break;
  234.         
  235.         case 'F': /* file start */
  236.             {
  237.                 char *tp;
  238.                 if( (tp = strchr(finbuff,'\n')) != (char *)NULL)
  239.                     *tp = '\0';
  240.                 strncpy(currentfnm, &finbuff[2], 100);
  241.                 currentfnm[99] = '\0';
  242.             }
  243.             lnumstk[currfstk++] = linenumber;
  244.             linenumber = 0;
  245.             break;
  246.         
  247.         case 'X': /* file resume */
  248.             {
  249.                 char *tp;
  250.                 if( (tp = strchr(finbuff,'\n')) != (char *)NULL)
  251.                     *tp = '\0';
  252.                 strncpy(currentfnm, &finbuff[2], 100);
  253.                 currentfnm[99] = '\0';
  254.             }
  255.             linenumber = lnumstk[--currfstk];
  256.             break;
  257.  
  258.         default:
  259.             frp2error("unknown intermediate file command");
  260.             break;
  261.         }
  262.     }
  263.  
  264.     if(hexflag)
  265.         flushhex();
  266.  
  267.     if(listflag)
  268.         flushlisthex();
  269. }
  270.  
  271. outeval()
  272. /*
  273.     description    convert the polish form character string in the 
  274.             intermediate file 'D' line to binary values in the
  275.             output result array.
  276.     globals        the output expression pointer
  277.             the output result array
  278. */
  279. {
  280.     register long etop = 0;
  281.  
  282.     register struct evstkel *estkm1p = &estk[0];
  283.  
  284.     while( *oeptr != '\0')
  285.     {
  286.         switch(*oeptr)
  287.         {
  288.         case '0':
  289.         case '1':
  290.         case '2':
  291.         case '3':
  292.         case '4':
  293.         case '5':
  294.         case '6':
  295.         case '7':
  296.         case '8':
  297.         case '9':
  298.             etop = (etop << 4) + ((*oeptr) - '0');
  299.             break;
  300.  
  301.         case 'a':
  302.         case 'b':
  303.         case 'c':
  304.         case 'd':
  305.         case 'e':
  306.         case 'f':
  307.             etop = (etop << 4) + ((*oeptr) - 'a' + 10);
  308.             break;
  309.         
  310.         case 'A':
  311.         case 'B':
  312.         case 'C':
  313.         case 'D':
  314.         case 'E':
  315.         case 'F':
  316.             etop = (etop << 4) + ((*oeptr) - 'A' + 10);
  317.             break;
  318.  
  319. #include "fraeuni.h"
  320. #include "fraebin.h"
  321.         case IFC_SYMB:
  322.             {
  323.                 struct symel *tsy;
  324.  
  325.                 tsy = symbindex[etop];
  326.                 if(tsy -> seg <= 0)
  327.                 {
  328.                     frp2undef(tsy);
  329.                     etop = 0;
  330.                 }
  331.                 else
  332.                 {
  333.                     if(tsy -> seg == SSG_EQU ||
  334.                        tsy -> seg == SSG_SET)
  335.                     {
  336.             frp2warn( "forward reference to SET/EQU symbol");
  337.                     }
  338.                     etop = tsy -> value;
  339.                 }
  340.             }
  341.             break;
  342.  
  343.         case IFC_CURRLOC: 
  344.             etop = genlocctr;
  345.             break;
  346.  
  347.         case IFC_PROGCTR:
  348.             etop = locctr;
  349.             break;
  350.  
  351.         case IFC_DUP:
  352.             if(estkm1p >= &estk[PESTKDEPTH-1])
  353.             {
  354.                 frp2error("expression stack overflow");
  355.             }
  356.             else
  357.             {
  358.                 (++estkm1p)->v = etop;
  359.             }
  360.             break;
  361.  
  362.         case IFC_LOAD:
  363.             if(estkm1p >= &estk[PESTKDEPTH-1])
  364.             {
  365.                 frp2error("expression stack overflow");
  366.             }
  367.             else
  368.             {
  369.                 (++estkm1p)->v = etop;
  370.             }
  371.             etop = 0;
  372.             break;
  373.  
  374.         case IFC_CLR:
  375.             etop = 0;
  376.             break;
  377.  
  378.         case IFC_CLRALL:
  379.             etop = 0;
  380.             estkm1p = &estk[0];
  381.             break;
  382.  
  383.         case IFC_POP:
  384.             etop = (estkm1p--)->v;
  385.             break;
  386.  
  387.         case IFC_TESTERR:
  388.             if(etop)
  389.             {
  390.                 frp2error(
  391.             "expression fails validity test");
  392.             }
  393.             break;
  394.  
  395.         case IFC_SWIDTH:
  396.             if( etop > 0 && etop <= MAXIMPWID)
  397.             {
  398.                 if( estkm1p->v < -(widthmask[etop-1]+1) ||
  399.                     estkm1p->v > widthmask[etop-1] )
  400.                 {
  401.                     frp2error(
  402.                 "expression exceeds available field width");
  403.                 }
  404.                 etop = ((estkm1p--)->v)  & widthmask[etop];
  405.             }
  406.             else
  407.                 frp2error("unimplemented width");
  408.             break;
  409.  
  410.         case IFC_WIDTH:
  411.             if( etop > 0 && etop <= MAXIMPWID)
  412.             {
  413.                 if( estkm1p->v < -(widthmask[etop-1]+1) ||
  414.                     estkm1p->v > widthmask[etop] )
  415.                 {
  416.                     frp2error(
  417.                 "expression exceeds available field width");
  418.                 }
  419.                 etop = ((estkm1p--)->v)  & widthmask[etop];
  420.             }
  421.             else
  422.                 frp2error("unimplemented width");
  423.             break;
  424.  
  425.         case IFC_IWIDTH:
  426.             if( etop > 0 && etop <= MAXIMPWID)
  427.             {
  428.                 if( estkm1p->v < 0 ||
  429.                     estkm1p->v > widthmask[etop] )
  430.                 {
  431.                     frp2error(
  432.                 "expression exceeds available field width");
  433.                 }
  434.                 etop = ((estkm1p--)->v)  & widthmask[etop];
  435.             }
  436.             else
  437.                 frp2error("unimplemented width");
  438.             break;
  439.  
  440.         case IFC_EMU8:
  441.             if( etop >= -128 && etop <= 255)
  442.             {
  443.                 o